<?php

namespace App\Http\Controllers;

use App\Models\User;
use Illuminate\Http\Request;
use Auth;
use Mail;

class UsersController extends Controller
{
    //
    public function __construct()
    {
        $this -> middleware('auth',[
            'except' => ['show','create','store','index','confirmEmail']
        ]);
        $this -> middleware('guest',[
            'only' => ['create']
        ]);
    }
    /*
     * 通过 except 方法来设定 指定动作 不使用 Auth 中间件进行过滤，
     * 意为 —— 除了此处指定的动作以外，所有其他动作都必须登录用户才能访问，
     * 类似于黑名单的过滤机制。相反的还有 only 白名单方法，将只过滤指定动作。
     * 我们提倡在控制器 Auth 中间件使用中，首选 except 方法，这样的话，
     * 当你新增一个控制器方法时，默认是安全的，此为最佳实践。
     * */

    public function create()
    {
        return view('users.create');
    }

    public function show(User $user)
    {
        $statuses = $user->statuses()
                            ->orderBy('created_at','desc')
                            ->paginate(30);
        return view('users.show',compact('user','statuses'));
        //用compact把User对象转换成数组绑定到视图上，这样就可以直接调用$user来获取内容
    }

    public function store(Request $request)
    {
        $this->validate($request, [
            'name' => 'required|max:50', //存在性验证：required 最大长度 max  最小长度 min
            'email' => 'required|email|unique:users|max:255', //邮箱格式验证 email   唯一性验证 unique
            'password' => 'required|confirmed|min:6'  //密码匹配验证 confirmed
        ]);
        /*
         * validate 方法接收两个参数，第一个参数为用户的输入数据，第二个参数为该输入数据的验证规则。
        */

        $user = User::create([
            'name' => $request->name,
            'email' => $request->email,
            'password' => bcrypt($request->password),
        ]);
        /*
         * 注册成功，把用户信息保存到数据库
         * */
        $this->sendEmailConfirmationTo($user); //验证邮箱
        session()->flash('success', '验证邮件已发送到你的注册邮箱上，请注意查收。');
        //我们想存入一条缓存的数据，让它只在下一次的请求内有效时，则可以使用 flash 方法。flash 方法接收两个参数，第一个为会话的键，第二个为会话的值.
        return redirect('/');
    }

    public function edit(User $user)
    {
        $this -> authorize('update',$user);//验证权限
        return view('users.edit',compact('user'));
    }

    public function update(Request $request,User $user)
    {
        $this -> validate($request,[
            'name' => 'required|max:50',
            'password' => 'nullable|confirmed|min:6'
        ]);

        $this -> authorize('update',$user);

        $data = [];
        $data['name'] = $request -> name;
        if($request->password){
            $data['password'] = bcrypt($request->password);
        }

        $user -> update($data);

        session()->flash('success', '个人资料更新成功！');

        return redirect()->route('users.show', $user->id);
    }

    public function index()
    {
        $users = User::paginate(10);
        return view('users.index',compact('users'));
    }

    public function destroy(User $user)
    {
        $this -> authorize('destroy',$user);
        $user -> delete();
        session()->flash('success', '成功删除用户！');
        return back();
    }

    protected function sendEmailConfirmationTo($user)
    {
        $view = 'emails.confirm';
        $data = compact('user');
        $from = 'aufree@yousails.com';
        $name = 'Aufree';
        $to = $user->email;
        $subject = "感谢注册 Sample 应用！请确认你的邮箱。";

        Mail::send($view, $data, function ($message) use ($to, $subject) {
            $message->to($to)->subject($subject);
        });
    }

    public function confirmEmail($token)
    {
        $user = User::where('activation_token',$token)->firstOrFail();

        $user->activated = true;
        $user->activation_token = null;
        $user->save();

        Auth::login($user);
        session()->flash('success', '恭喜你，激活成功！');
        return redirect()->route('users.show', [$user]);
    }

    public function followings(User $user)
    {
        $users = $user->followings()->paginate(30);
        $title = '关注的人';
        return view('users.show_follow', compact('users', 'title'));
    }

    public function followers(User $user)
    {
        $users = $user->followers()->paginate(30);
        $title = '粉丝';
        return view('users.show_follow', compact('users', 'title'));
    }

}
